//
//  DemoSnapshotScroll.m
//  ocdemo
//
//  Created by JIENING ZHANG on 2020/3/26.
//  Copyright © 2020 JIENING ZHANG. All rights reserved.
//

#import "DemoSnapshotScroll.h"
#import "LZKButtonAddition.h"
#import "LZKViewAddition.h"
#import "LZKImageAddition.h"

@interface DemoSnapshotScroll()

@property (nonatomic, strong) UIScrollView *scrollView;

@end

@implementation DemoSnapshotScroll

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    
    self.title = @"Snapshot Scroll";
    self.view.backgroundColor = [UIColor whiteColor];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    _scrollView = [[UIScrollView alloc]initWithFrame:self.view.bounds];
    _scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    [self.view addSubview:_scrollView];
    
    CGFloat offsetY = 50;
    for(int j=0; j<80; j++) {
        UILabel *tipsLabel = [[UILabel alloc] initWithFrame:CGRectMake(30, offsetY, 300, 20)];
        tipsLabel.text = [NSString stringWithFormat:@"tipsLabel : %d", j];
        tipsLabel.textColor = [UIColor blackColor];
        tipsLabel.font = [UIFont systemFontOfSize:18];
        [_scrollView addSubview:tipsLabel];
        
        // 行动按钮 top
        UIButton* snapButton = [[UIButton alloc]initWithFrame:CGRectMake(230, offsetY, 120, 32)];
        snapButton.layer.masksToBounds = YES;
        snapButton.layer.cornerRadius = 8;
        snapButton.titleForStateNormal=@"timer demo";
        snapButton.titleColorForStateNormal = [UIColor whiteColor];
        snapButton.backgroundColorForStateNormal = [UIColor grayColor];
        [snapButton addTarget:self action:@selector(onSnapButtonTouch:) forControlEvents:UIControlEventTouchUpInside];
        
        [_scrollView addSubview:snapButton];
        
        offsetY += 40;
    }
    
    _scrollView.contentSize = CGSizeMake(_scrollView.bounds.size.width, offsetY);
}


- (void)onSnapButtonTouch:(id)sender {
    UIImage *snapImage = [self snapshotScrollView];
    if(snapImage) {
        [UIImage saveImage2PHPhotoLibrary:snapImage];
    }
}

// ipad 横屏 scrollview的截图，snapshotScrollViewOld 逻辑会失效
// 卷动scrollview，截多张图，最后拼接起来虽然麻烦，但是可行
//   实践起来，需要注意两点
//     1. scrollview 直接 call drawViewHierarchyInRect 做一张截图，不能如预期正常work
//         需要把scrollview 先拎出来，加到一个view上，对这个view 调用 drawViewHierarchyInRect
//     2. scrollview最后一部分，需要做图片裁切，使用 CGImageCreateWithImageInRect，会自动将带上 [UIScreen mainScreen].scale 效果
//         者其实是因为做截图的时候 UIGraphicsBeginImageContextWithOptions 使用 [UIScreen mainScreen].scale，
//         截图出来的UIImage有scale，变成CGImage 做裁切就会加倍尺寸
//         所以裁剪图片时，坐标也要带上 scale, 裁切后, CGImage 变 UIImage，要把图片缩回去

- (UIImage *)snapshotScrollView
{
    UIImage* image = nil;
    //    UIGraphicsBeginImageContext(_scrollView.contentSize);
    //int scrollViewWidth = _scrollView.width;
    int scrollContentHeight = _scrollView.contentSize.height;

    CGPoint savedContentOffset = _scrollView.contentOffset;
    CGRect savedFrame = _scrollView.frame;

    CGFloat offsetY = 0;
    CGFloat drawHeight = _scrollView.height;
    NSMutableArray *imageArr = [NSMutableArray array];
    CGFloat buttom2Render = -1;
    CGFloat mergeHeight = 0;
    
    //     1. scrollview 直接 call drawViewHierarchyInRect 做一张截图，不能如预期正常work
    //         需要把scrollview 先拎出来，加到一个view上，对这个view 调用 drawViewHierarchyInRect
    UIView *tmp2RenderScroll = [[UIView alloc]initWithFrame:_scrollView.bounds];
    [tmp2RenderScroll addSubview:_scrollView];
    
    while(YES) {
        @autoreleasepool {
            _scrollView.contentOffset = CGPointMake(0, offsetY);
            //_scrollView.frame = CGRectMake(0, 0, scrollViewWidth, scrollViewHeight);
            CGRect drawBound = CGRectMake(0, offsetY, _scrollView.width, drawHeight);
            if (buttom2Render > 0) {
                drawHeight = buttom2Render;
                drawBound = CGRectMake(0, _scrollView.height-buttom2Render, _scrollView.width, buttom2Render);
            }
            
            UIGraphicsBeginImageContextWithOptions(CGSizeMake(tmp2RenderScroll.width, tmp2RenderScroll.height), NO, [UIScreen mainScreen].scale);
            [tmp2RenderScroll drawViewHierarchyInRect:tmp2RenderScroll.bounds afterScreenUpdates:YES];
           
            UIImage *subImage = UIGraphicsGetImageFromCurrentImageContext();
            UIGraphicsEndImageContext();
                
            if (subImage) {
                if (buttom2Render > 0) {
                    //将UIImage转换成CGImageRef
                    CGImageRef sourceImageRef = [subImage CGImage];
                    //按照给定的矩形区域进行剪裁
                    // sourceImageRef 会带上 [UIScreen mainScreen].scale 效果，也就是高分屏会加倍图片尺寸，所以裁剪图片时，坐标也要带上 scale
                    CGFloat msScale = [UIScreen mainScreen].scale;
                    CGFloat cropTop = tmp2RenderScroll.height - buttom2Render;
                    CGImageRef newImageRef = CGImageCreateWithImageInRect(sourceImageRef, CGRectMake(0, cropTop*msScale, tmp2RenderScroll.width*msScale, buttom2Render*msScale));
                    //将CGImageRef转换成UIImage
                    UIImage *newImage = [UIImage imageWithCGImage:newImageRef];
                    //释放创建的CGImageRef，其内存已经被newImage持有一次，此处必须释放
                    CGImageRelease(newImageRef);
                    
                    if(newImage) {
                        //     2. scrollview最后一部分，需要做图片裁切，使用 CGImageCreateWithImageInRect，会自动将带上 [UIScreen mainScreen].scale 效果
                        //         者其实是因为做截图的时候 UIGraphicsBeginImageContextWithOptions 使用 [UIScreen mainScreen].scale，
                        //         截图出来的UIImage有scale，变成CGImage 做裁切就会加倍尺寸
                        //         所以裁剪图片时，坐标也要带上 scale, 裁切后, CGImage 变 UIImage，要把图片缩回去
                        if (msScale > 1){
                            UIGraphicsBeginImageContext(CGSizeMake(tmp2RenderScroll.width, buttom2Render));
                            [newImage drawInRect:CGRectMake(0, 0, tmp2RenderScroll.width, buttom2Render)];
                            UIImage *reSizeImage = UIGraphicsGetImageFromCurrentImageContext();
                            UIGraphicsEndImageContext();
                            if(reSizeImage) {
                                subImage = reSizeImage;
                            }
                        } else {
                            subImage = newImage;
                        }
                    }
                }
                
                [imageArr addObject:subImage];
                mergeHeight += subImage.size.height;
            }
        } // end of @autoreleasepool
        
        if (buttom2Render > 0) {
            break;
        }
        
        if (scrollContentHeight <= offsetY + _scrollView.height) {
            break;
        }
        
        if (scrollContentHeight < offsetY + 2*(_scrollView.height)) {
            buttom2Render = scrollContentHeight - offsetY - _scrollView.height;
            offsetY += buttom2Render;
        } else {
            offsetY += drawHeight;
        }
    }
    _scrollView.contentOffset = savedContentOffset;
    _scrollView.frame = savedFrame;
    
    [self.view insertSubview:_scrollView atIndex:0];
    
    if([imageArr count] == 1) {
        image = [imageArr firstObject];
    } else {
        
        // 卷动scrollview，截多张图，最后拼接起
        CGFloat mergeWidth = _scrollView.width;
        UIGraphicsBeginImageContext(CGSizeMake(mergeWidth, mergeHeight));
        CGFloat offsetY = 0;
        
        for (UIImage *img in imageArr) {
            [img drawInRect:CGRectMake(0, offsetY, img.size.width, img.size.height)];
            offsetY += img.size.height;
        }
        image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        
        [imageArr removeAllObjects];
    }
    
    return image;
}

//淘长图
- (UIImage *)snapshotScrollViewOld
{
    UIImage* image = nil;
    //    UIGraphicsBeginImageContext(_scrollView.contentSize);
    int scrollViewWidth = _scrollView.contentSize.width;
    int scrollViewHeight = _scrollView.contentSize.height;

    CGPoint savedContentOffset = _scrollView.contentOffset;
    CGRect savedFrame = _scrollView.frame;
    
    UIView *tmp2RenderScroll = [[UIView alloc]initWithFrame:CGRectMake(0, 0, scrollViewWidth, scrollViewHeight)];
    [tmp2RenderScroll addSubview:_scrollView];
    _scrollView.contentOffset = CGPointZero;
    _scrollView.frame = CGRectMake(0, 0, scrollViewWidth, scrollViewHeight);
    
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(scrollViewWidth, scrollViewHeight), NO, [UIScreen mainScreen].scale);
    {
        //[_scrollView.layer renderInContext: UIGraphicsGetCurrentContext()];
        [tmp2RenderScroll drawViewHierarchyInRect:tmp2RenderScroll.bounds afterScreenUpdates:YES];
        image = UIGraphicsGetImageFromCurrentImageContext();
    }
    UIGraphicsEndImageContext();
    
    _scrollView.contentOffset = savedContentOffset;
    _scrollView.frame = savedFrame;
    [self.view addSubview:_scrollView];
    
    return image;
}

@end
